#ifndef DRIVER_H_
#define DRIVER_H_

#include "ReservedTable.h"
#include "ErrorPrinter.h"
#include "SymbolsTable.h"
#include "CodeGenerator.h"

namespace LALG
{

class Driver
{

public:

    /*-----------------------------------------------------------------------------
     *  Constrói um driver passando o arquivo de entrada do código-fonte
     *-----------------------------------------------------------------------------*/
    Driver(const string& filename);

    /*-----------------------------------------------------------------------------
     *  Destrói o driver
     *-----------------------------------------------------------------------------*/
    virtual ~Driver();

    /*-----------------------------------------------------------------------------
     *  Faz o parseamento
     *-----------------------------------------------------------------------------*/
    bool parse(const string &out);

    /*-----------------------------------------------------------------------------
     *  Salva a linha e o token atual
     *-----------------------------------------------------------------------------*/
    void saveCurrent();

    /*-----------------------------------------------------------------------------
     *  Salva a linha atual
     *-----------------------------------------------------------------------------*/
    void saveLine();

    /*-----------------------------------------------------------------------------
     *  Imprime um erro léxico
     *-----------------------------------------------------------------------------*/
    void lexError(ErrorWhat what, string text);

    /*-----------------------------------------------------------------------------
     *  Imprime um erro sintático
     *-----------------------------------------------------------------------------*/
    void sinError(ErrorWhat what, int synToken = 0);

    /*-----------------------------------------------------------------------------
     *  Imprime um erro semântico
     *-----------------------------------------------------------------------------*/
    void semError(ErrorWhat what, string text);

    /*-----------------------------------------------------------------------------
     *  Tabela de símbolos do programa
     *-----------------------------------------------------------------------------*/
    SymbolsTable symbols;

    /*-----------------------------------------------------------------------------
     *  Gerador de código
     *-----------------------------------------------------------------------------*/
    CodeGenerator generator;

    /*-----------------------------------------------------------------------------
     *  Analisador léxico
     *-----------------------------------------------------------------------------*/
    class Scanner *scanner;

    friend class Scanner;
    friend class Parser;

private:

    /*-----------------------------------------------------------------------------
    *  Nome do arquivo de entrada
    *-----------------------------------------------------------------------------*/
   string filename;

   /*-----------------------------------------------------------------------------
    *  Stream de entrada
    *-----------------------------------------------------------------------------*/
   ifstream istream;

   /*-----------------------------------------------------------------------------
    *  Analisador sintático
    *-----------------------------------------------------------------------------*/
   class Parser *parser;

    /*-----------------------------------------------------------------------------
     *  Contêiner de erros
     *-----------------------------------------------------------------------------*/
    ErrorPrinter errors;

    /*-----------------------------------------------------------------------------
     *  Tabela de símbolos e palavras reservadas
     *-----------------------------------------------------------------------------*/
    ReservedTable reserved;

    /*-----------------------------------------------------------------------------
     *  Linha de uma regra
     *-----------------------------------------------------------------------------*/
    int ruleLine;

    /*-----------------------------------------------------------------------------
     *  Linha salva
     *-----------------------------------------------------------------------------*/
    int savedLine;

    /*-----------------------------------------------------------------------------
     *  Token salvo
     *-----------------------------------------------------------------------------*/
    string savedToken;

};

}

#endif
